// @Author EthanScriptOn
// @Desc
package config_parser

import (
	"errors"
	"gitee.com/fatzeng/srf_switch_config/config_context"
	"gitee.com/fatzeng/srf_switch_config/config_define"
	"gitee.com/fatzeng/srf_switch_config/config_node"
	"gitee.com/fatzeng/srf_switch_config/config_source_loader"
	"gitee.com/fatzeng/srf_switch_protocol/protocol/log"
)

type FundamentalParserConfigurator struct {
	ResourceParser
	parseResult      map[string]interface{}
	configSourceType config_define.ConfigSourceType
}

func GenerateFundamentalParserConfigurator() *FundamentalParserConfigurator {
	return &FundamentalParserConfigurator{
		parseResult: make(map[string]interface{}),
	}
}

func (f *FundamentalParserConfigurator) ParsePrepare(ctx *config_context.ConfigInitializationContext) (err error) {
	log.Logger().Info("You can implement this function to perform some preprocessing operations")
	return
}

func (f *FundamentalParserConfigurator) ParseDoMore(ctx *config_context.ConfigInitializationContext) (err error) {
	log.Logger().Info("You can implement this function to perform some post operations")
	return
}

func (f *FundamentalParserConfigurator) StageParseResultDoMore(ctx *config_context.ConfigInitializationContext) (err error) {
	log.Logger().Info("You can implement this function to perform some post operations")
	return
}

func (f *FundamentalParserConfigurator) Parse(ctx *config_context.ConfigInitializationContext, unresolvedData interface{}) error {
	loaderResult, ok := unresolvedData.(*config_source_loader.SourceLoaderResult)
	if !ok {
		return errors.New("FundamentalParserConfigurator can only handle data of type *SourceLoaderResult Please check the loading result of the source loader")
	}
	f.parseResult = f.MergeDuplicateRemovalLoaderResult(loaderResult.GetSegmentsInformation())
	f.configSourceType = loaderResult.GetConfigSourceType()
	return nil
}

func (f *FundamentalParserConfigurator) MergeDuplicateRemovalLoaderResult(segments []*config_source_loader.SegmentInformation) map[string]interface{} {
	loaderResult := make(map[string]interface{})
	for _, segment := range segments {
		segmentResult := segment.GetSegmentLoaderResult()
		for key, val := range segmentResult {
			loaderResult[key] = val
		}
	}
	return loaderResult
}

func (f *FundamentalParserConfigurator) StoreDuplicateMergerResult(parseResultNode *config_node.ParseResultPackageNode, duplicateMergerResult map[string]interface{}) {
	for nodeType, segmentVal := range duplicateMergerResult {
		parseResultNode.StoreGroupResult(config_define.NodeElemType(nodeType), segmentVal)
	}
}

func (f *FundamentalParserConfigurator) GetStageParseResult(ctx *config_context.ConfigInitializationContext) interface{} {
	return f.parseResult
}

func (f *FundamentalParserConfigurator) StageParseResult(ctx *config_context.ConfigInitializationContext) error {
	resultNode := config_node.GenerateParseResultPackageNode()
	f.StoreDuplicateMergerResult(resultNode, f.parseResult)
	return ctx.GetResultCoordinator().StoreResult(config_define.ConfigSourceTypeFreightMapping[f.configSourceType], resultNode)
}
